import { useCallback, useEffect, useRef } from 'react';
import useUpdateEffect from './useUpdateEffect';

function useDebounceFn(fn?:any, deps?:any, wait?:any) {
  const _deps = Array.isArray(deps) ? deps : [];
  const _wait = typeof deps === 'number' ? deps : wait || 0;
  const timer:any = useRef();

  const fnRef = useRef(fn);
  fnRef.current = fn;

  const cancel = useCallback(() => {
    if (timer.current) {
      clearTimeout(timer.current);
    }
  }, []);

  const run = useCallback(
    (...args) => {
      cancel();
      timer.current = setTimeout(() => {
        fnRef.current(...args);
      }, _wait);
    },
    [_wait, cancel],
  );

  useUpdateEffect(() => {
    run();
    return cancel;
  }, [..._deps, run]);

  useEffect(() => cancel, []);

  return {
    run,
    cancel,
  };
}

export default useDebounceFn;